package com.jcj.jcjconfig.client.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class JcjConfigServiceImpl implements JcjConfigService {

    Map<String, String> config;
    ApplicationContext applicationContext;

    public JcjConfigServiceImpl(ApplicationContext applicationContext, Map<String, String> config) {
        this.applicationContext = applicationContext;
        this.config = config;
    }

    @Override
    public String[] getPropertyNames() {
        return this.config.keySet().toArray(new String[0]);
    }

    @Override
    public String getProperty(String name) {
        return this.config.get(name);
    }

    @Override
    public void onChange(ChangeEvent event) {
        Set<String> keys = calcChangedKeys(this.config, event.config());
        if (keys.isEmpty()) {
            log.info("[JCJ-CONFIG] calcChangedKeys return empty, ignore update.");
            return;
        }
        if (!config.isEmpty()) {
            log.info("config已变更,{}", keys);
            applicationContext.publishEvent(new EnvironmentChangeEvent(keys));
        }
    }

    /**
     * 计算变更的key
     *
     * @param oldConfigs
     * @param newConfigs
     * @return
     */
    private Set<String> calcChangedKeys(Map<String, String> oldConfigs, Map<String, String> newConfigs) {
        if (oldConfigs.isEmpty()) {
            return newConfigs.keySet();
        }
        if (newConfigs.isEmpty()) {
            return oldConfigs.keySet();
        }
        Set<String> news = newConfigs.keySet().stream()
                .filter(key -> !newConfigs.get(key).equals(oldConfigs.get(key)))
                .collect(Collectors.toSet());
        oldConfigs.keySet().stream().filter(key -> !newConfigs.containsKey(key))
                .forEach(key -> news.add(key));
        return news;
    }
}
